-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
X3: Kleene star can't into single-element sequence #178
base: develop
Are you sure you want to change the base?
Conversation
This will fail to compile with error "'value_type': is not a member of 'ast::a3'". #include <boost/spirit/home/x3.hpp> #include <boost/spirit/home/x3/support/ast/variant.hpp> #include <boost/fusion/include/define_struct_inline.hpp> #include <string> #include <vector> namespace ast { BOOST_FUSION_DEFINE_STRUCT_INLINE ( a1, (std::string, v) ) BOOST_FUSION_DEFINE_STRUCT_INLINE ( a2, (a1, v1) (std::vector<double>, v2) ) BOOST_FUSION_DEFINE_STRUCT_INLINE ( a3, (std::vector<a2>, v1) ) } using namespace boost::spirit::x3; auto a1 = rule<class i1, ast::a1>{} = lexeme[+alpha]; auto a2 = rule<class i2, ast::a2>{} = a1 >> '(' >> -(double_ % ',') >> ')'; auto a3 = rule<class i3, ast::a3>{} = *(a2 >> ';'); using data = ast::a3; int main() { std::string script = "foo(1,2,3);"; auto begin = script.begin(); auto end = script.end(); data v; bool ok = (boost::spirit::x3::phrase_parse(begin, end, a3, space, v) && begin == end); } Fixed by adding container_value specialization: for single-element fusion sequence return container_value of that one element.
Btw, adding #define BOOST_SPIRIT_X3_DEBUG will break this sample program again. |
I'm not sure about this one. Why do you have to wrap the container into a fusion vector? Why not simply use std::vector and std::vectorstd::vector ? |
Why not? I'm not saying "you have to". This might be the result of simplification of some existing code. Do you want to not to compile simpler version of the code? Then If I'd adapting the existring struct, I could write Why |
Btw,
to this
And now it suddenly requires |
I'll have to think about this some more as it introduces a new behavior. The previous behavior in which you provided a patch for is suspicious to begin with. What we should probably do is to distill the test code to the bare essentials so I (we) can analyze and reason out with the correct behavior. I fear that we are opening a can of worms if we allow single-element-tuple-with-container == container. |
MWE: #include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/define_struct_inline.hpp>
#include <string>
namespace ast
{
BOOST_FUSION_DEFINE_STRUCT_INLINE
(
a3,
(std::vector<int>, v1)
)
}
int main()
{
namespace x3 = boost::spirit::x3;
auto test = [](std::string s, auto&& p)
{
ast::a3 v;
auto it = s.begin();
return (x3::phrase_parse(it, s.end(), p, x3::space, v) && it == s.end());
};
test("1 2 3 ", *x3::int_); // OK
test("1;2;3 ", x3::int_ % ';'); // OK
test("1;2;3;", *(x3::int_ >> ';')); // Fail to compile
} |
This will fail to compile with error "'value_type': is not a member of 'ast::a3'".
Fixed by adding container_value specialization: for single-element fusion sequence return container_value of that one element.